const Config = require('./config');
const publicIp = require('public-ip');

/******************************************************阿里云start**********************************************************/
const Core = require('@alicloud/pop-core');
const AliClient = new Core({
    accessKeyId: Config.accessKeyId,
    accessKeySecret: Config.accessKeySecret,
    endpoint: 'https://alidns.cn-hangzhou.aliyuncs.com',
    apiVersion: '2015-01-09'
});

// 添加阿里云解析记录
function addDomainRecord(params = {}) {
    let requestOption = {
        method: 'POST'
    };
    return new Promise((resolve,reject) => {
        AliClient.request('AddDomainRecord', params, requestOption).then((result) => {
           resolve(result)
        }, (ex) => {
           reject(ex)
        })
    })
}

// 获取阿里云解析列表
function getDomainRecords() {
    let { DomainName } = Config
    let params = {
        DomainName,
    }
    let requestOption = {
        method: 'POST'
    };
    return new Promise((resolve,reject) => {
        AliClient.request('DescribeDomainRecords', params, requestOption).then((result) => {
           resolve(result.DomainRecords.Record)
        }, (ex) => {
           reject(ex)
        })
    })
}

// 更新阿里云解析记录
function updateDomainRecord(params = {}) {
    let requestOption = {
        method: 'POST'
    };
    return new Promise((resolve,reject) => {
        AliClient.request('UpdateDomainRecord', params, requestOption).then((result) => {
           resolve(result)
        }, (ex) => {
           reject(ex)
        })
    })
}

async function task(recordsList,subDomainName,type = 'v4') {
    let { DomainName } = Config
    let typeMap = {'v4':'A','v6':'AAAA'}
    if(subDomainName) {
        console.log('更新的类型:' + type)
        let target = recordsList.find(item => {
            return item.RR === subDomainName && item.Type === typeMap[type]
        })
        let targetDomain = `${subDomainName}.${DomainName}`
        // 获取本机ip
        let ip = ''
        if(type === 'v4') {
            ip = await publicIp.v4()
        }else if(type === 'v6') {
            ip = await publicIp.v6()
        }

        console.log(`本机公网ip:${ip}`);

        if(target) {
            let {Value,RecordId,Type,RR} = target
            console.log(`域名:${targetDomain} 阿里记录:${Value}`);
            // 判断ip是否相等
            if(ip === Value) {
                console.log('本机记录与阿里记录一致,无需更新!')
            }else {
                // 修改记录
                await updateDomainRecord({RecordId,Type:typeMap[type],RR,Value:ip})
                console.log(`域名:${targetDomain} 已更新! 值为:${ip}`)
            }
        }else {
            // 添加记录
            console.log(`域名:${targetDomain} 不存在解析记录!`)
            let params = {DomainName,RR:subDomainName,Type:typeMap[type],Value:ip}
            await addDomainRecord(params)
            console.log(`域名:${targetDomain} 已添加! 值为:${ip}`)
        }
    }
}
/******************************************************阿里云end**********************************************************/

/******************************************************腾讯云start**********************************************************/
const tencentcloud = require("tencentcloud-sdk-nodejs-dnspod");
const DnspodClient = tencentcloud.dnspod.v20210323.Client;
const clientConfig = {
    credential: {
        secretId: Config.accessKeyId,
        secretKey: Config.accessKeySecret,
    },
    region: "",
    profile: {
        httpProfile: {
            endpoint: "dnspod.tencentcloudapi.com",
        },
    },
};
const client = new DnspodClient(clientConfig);

// 获取腾讯云解析列表
function getTcDomainRecords() {
    let { DomainName } = Config
    let params = {
        "Domain": DomainName,
        "Limit":3000
    }
    return new Promise((resolve,reject) => {
        client.DescribeRecordList(params).then(
            (data) => {
                resolve(data.RecordList)
            },
            (err) => {
                reject(err)
            }
        );
    })
}

// 添加腾讯云解析记录
function addTcDomainRecord(params = {}) {
    return new Promise((resolve,reject) => {
        client.CreateRecord(params).then(
            (data) => {
                resolve(data)
            },
            (err) => {
                reject(err)
            }
        );
    })
}

// 更新腾讯云解析记录
function updateTcDomainRecord(params = {}) {
    return new Promise((resolve,reject) => {
        client.ModifyRecord(params).then(
            (data) => {
                resolve(data)
            },
            (err) => {
                reject(err)
            }
        );
    })
}

async function taskTc(recordsList,subDomainName,type = 'v4') {
    let { DomainName } = Config
    let typeMap = {'v4':'A','v6':'AAAA'}
    if(subDomainName) {
        console.log('更新的类型:' + type)
        let target = recordsList.find(item => {
            return item.Name === subDomainName && item.Type === typeMap[type]
        })
        let targetDomain = `${subDomainName}.${DomainName}`
        // 获取本机ip
        let ip = ''
        if(type === 'v4') {
            ip = await publicIp.v4()
        }else if(type === 'v6') {
            ip = await publicIp.v6()
        }

        console.log(`本机公网ip:${ip}`);

        if(target) {
            let {Value,RecordId,RecordType,Name} = target
            console.log(`域名:${targetDomain} 腾讯记录:${Value}`);
            // 判断ip是否相等
            if(ip === Value) {
                console.log('本机记录与腾讯记录一致,无需更新!')
            }else {
                // 修改记录
                let params = {Domain:DomainName,SubDomain:Name,RecordType:typeMap[type],RecordLine:'默认',Value:ip,RecordId:RecordId}
                await updateTcDomainRecord(params)
                console.log(`域名:${targetDomain} 已更新! 值为:${ip}`)
            }
        }else {
            // 添加记录
            console.log(`域名:${targetDomain} 不存在解析记录!`)
            let params = {Domain:DomainName,SubDomain:subDomainName,RecordType:typeMap[type],RecordLine:'默认',Value:ip}
            await addTcDomainRecord(params)
            console.log(`域名:${targetDomain} 已添加! 值为:${ip}`)
        }
    }
}
/******************************************************腾讯云end**********************************************************/

async function ddns() {
    let { domainList } = Config
    let ftype = Config.type
    let recordsList ;
    try {
        if(ftype==='2'){
            recordsList = await getTcDomainRecords()
        }else{
            recordsList = await getDomainRecords()
        }
    }catch (e) {
        console.log(e)
    }
    for (let i = 0; i < domainList.length; i++) {
        let {type,subDomainName} = domainList[i]
        try {
            if(ftype==='2'){
                await taskTc(recordsList,subDomainName,type)
            }else{
                await task(recordsList,subDomainName,type)
            }
        }catch (e) {
            console.log(e)
        }
    }
}

//先执行一次
ddns()
setInterval(ddns,Config.intervalTime * 60000)
